מבוא, משתנים, טיפוסים, אופרטורים, תנאים

Contents

מבוא, משתנים, טיפוסים, אופרטורים, תנאים#

הקדמה#

מטרות הקורס#

  • לפתח מיומנויות בסיסיות של תכנות וחשיבה אלגוריתמית

    • לא עוסק בפעולת החומרה של המחשב

תוכנית הלימודים:#

  • יסודות התכנות ב-Python

  • רקורסיה

  • תכנות מונחה עצמים

  • חישובים מדעיים (Numpy)

  • עיבוד תמונה (Numpy)

  • ניתוח נתונים (Pandas)

  • הצגת נתונים (Pandas)

בקליפת אגוז#

  • אין צורך בידע מוקדם

  • עם זאת, הקצב מהיר

  • הדרך היחידה להישאר בעניינים היא תרגול

מנהלה#

אתר הקורס: http://courses.cs.tau.ac.il/pyProg/2425b/#

  • ניהול הקורס

  • לוח זמנים

  • מצגות

  • מחברות Jupyter

  • מדריכי התקנה

  • מקורות חיצוניים

  • שיעורי בית

מודל: https://moodle.tau.ac.il/course/view.php?id=50918202098#

  • הגשת שיעורי בית

  • פורומים (כללי ולמטלות)

קיים גם מודל נפרד לכל תרגול (הודעות של עוזרי הוראה וכו’)#

תרגול#

  • מפגשים מעשיים

  • בכיתת מחשבים סטנדרטית

  • מטרות:

    • מחברות Jupyter

      • תרגול הנושאים שנלמדו בהרצאה

      • התנסות מעשית בכלים כמו PyCharm

    • רקע לקראת פתרון המטלות

שיעורי בית#

  • הנחיות תחת לשונית “תרגילים” באתר הקורס

  • הרבה התנסות מעשית

  • אין דרך אחרת ללמוד תכנות!

איפה אפשר לעבוד?#

  • מעבדות מחשבים

  • שעות וכתובות מופיעות באתר הקורס

    • לגבות עם אימייל / דיסק און קי / Dropbox וכו’!

הנחיות הגשה#

  • הגשה בודדת בלבד!

  • 7 תרגילים

  • חובה להגיש לפחות 6

  • ממוצע של 6 הטובים ביותר מהווה 25% מהציון הסופי

  • 10 ימי חסד

מעבדה מונחית#

  • מפגש מעשי אופציונלי במעבדת מחשבים

  • תמיכה טכנית (PyCharm, מחברות Jupyter וכו’)

  • מומלץ להשתמש!

הבחינה#

  • הציון הסופי מורכב מהממוצע של המטלות וציוני הבחינה

  • חובה לעבור את הבחינה כדי לעבור את הקורס

  • בחינה בכתב

  • כוללת את כל חומר הקורס:

    • הרצאות, תרגולים ושיעורי בית

הנושאים להיום#

  • רקע קצר על תכנות

  • יסודות Python:

    • משתנים (int, float, string, boolean)

    • אופרטורים (חשבון, השוואה, לוגיים)

רקע#

יסודות שפות תכנות#

  • תוכנית מחשב היא רצף של הוראות טקסט שניתן “להבין” על ידי מחשב ולהריץ.

  • שפת תכנות היא שפה מלאכותית, קריאה למכונה, שנועדה לבטא חישובים שניתן לבצע במחשב.

  • בויקיפדיה מופיעות מעל 500 שפות תכנות שונות.

קוד מכונה (שפת מכונה)#

  • המחשב מבין אך ורק שפת מכונה, המורכבת מרצפים של אפסים ואחדות.

  • צפו כעת סרטון על מנת להבין כיצד מספרים מיוצגים בשפת מכונה

%%html
<iframe width="560" height="315" src="https://www.youtube.com/embed/WYkkkM6vCx0?si=NstLcocgJ9vKoLtR" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

משפת מכונה לשפת תכנות (ולהיפך)#

  • מעבר לייצוג מספרים, ניתן לייצג במחשב גם פקודות באמצעות שפות מכונה.

  • שפות המכונה מאוד לא נוח לעבודה ולא אינטואיטיבית לבני אדם, ולכן פותחו שפות תכנות שונות כמו Python, Java ו-C על מנת לגשר על פער זה.

  • בני האדם כותבים בשפת תכנות. על מנת לבצע פקודות אלו (או “להריץ את התכנית”), מחשב תחילה “מתרגם” את שפת התכנות לשפת מכונה.

  • בקורס הזה, לא נעסוק באיך המחשב מבצע את התרגום הזה.

תוכנית מחשב#

  • רצף של הוראות שנועד להשיג מטרה מסוימת.

  • ההוראות מתבצעות לפי סדר. אף הוראה לא מתבצעת לפני שההוראה הקודמת הושלמה.

Python#

  • מאז 1991

  • קל ללמידה

  • זמן פיתוח קצר

  • מהיר מספיק לרוב היישומים

  • קהילה עצומה

  • בשימוש נרחב בתעשייה

  • Machine Learning

התקנה והרצה של Python#

לפניכם תוכנית קצרה בפייתון. לחצו על כפתור ההרצה (Run) וצפו בפלט של התוכנית בחלק התחתון של החלונית.

בעולם מדעי המחשב ישנה מוסכמה מקובלת שהתוכנית הראשונה שכותבים כאשר לומדים שפת תכנות חדשה היא תוכנית שמדפיסה למסך את המילים “Hello World!”

print("Hello World!")
Hello World!

הקדמה לפייתון#

משתנים, טיפוסים ואופרטורים#

סוגי נתונים (טיפוסים/types) ב-Python#

  • טיפוסים נפוצים:

    • מספריים: int ,float

    • לוגיים/בוליאניים: bool

    • טקסט/מחרוזת: str

  • למה צריך סוגים שונים?

    • חיסכון בזיכרון

    • מהירות ביצוע

    • לכל טיפוס יש פעולות ייחודיות (אופרטורים)

      • לדוגמא, בטיפוסים במספריים ניתן לבצע פעולות חיבור וחיסור

במודול זה נרחיב על כל טיפוס ואילו פועלות ניתן לעשות עליו#

טיפוסים מספריים: int וfloat#

# This is my first Python program!
print(13)
print(10)
print(1+2)
print       (      7    -      4   )
print(3*8) # This line prints 24
print(10/4)
print(2.3+1.7)
print(17 - 3*5)
print((17 - 3)*5)
13
10
3
3
24
2.5
4.0
2
70

בסרטון הכרנו את הטיפוסים המספריים וראינו כיצד לבצע פעולות חשבון בסיסיות על מספרים. ראינו שם שפייתון יודע לעבוד עם מספרים שמכילים נקודה עשרונית, כמו למשל 3.14 או 4.0.

בפייתון, מספרים עם ובלי נקודה עשרונית הם שני סוגים שונים של נתונים. באופן כללי במדעי המחשב, סוגי הנתונים השונים נקראים טיפוסי-נתונים (data-types) או מחלקות (classes). לכל טיפוס יש דרך מסויימת שבה הוא מיוצג בזיכרון של המחשב.

מספרים שלמים ללא נקודה עשרונית, כמו המספרים 4, 0 או 56 - שייכים למחלקה שנקראת int, שזה קיצור של integer, “מספר שלם” באנגלית.

לעומת זאת, מספרים שמכילים נקודה עשרונית כמו 3.14 שייכים למחלקה אחרת שנקרא float, זה קיצור של floating point או “נקודה צפה”, על שם הייצוג מספר עם נקודה עשרונית.

אפשר לערב באותו ביטוי מספרים משתי המחלקות האלו – int ו-float. למשל, החישוב 1+2.5 יתן לנו 3.5. תוצאת החישוב שייכת לטיפוס float כמובן.

באופן כללי, אם ביטוי חשבוני מכיל גם ערכים מטיפוס int וגם ערכים מטיפוס float, התוצאה תהיה מטיפוס float.

אבל יש מקרים שבהם ביטוי מכיל רק מספרים שלמים מטיפוס int, ועדיין התוצאה היא מספר עם נקודה עשרונית. זה מה שקורה כשמחלקים שני מספרים. למשל, אם תדפיסו את תוצאה החישוב print(10/4) תקבלו 2.5, מספר מטיפוס float, ואיפול אם תחלקו את 10 ב2 print(5/10) תקבלו 2.0, מספר מטיפוס float, בעוד 2 (בלי הנקודה העשרונית) הוא מטיפוס int.

בהמשך נכיר עוד טיפוסים בשפת פייתון, כאלה שלא מייצגים מספרים אלא סוגי נתונים אחרים.

עד כה ראינו את האופרטורים החשבוניים חיבור (+), חיסור (-), כפל (*), וחילוק (/).

כעת נכיר האופרטור //, או floor division.

האופרטור // נותן לנו רק את החלק השלם של תוצאת החלוקה. חלק זה נקרא גם המנה של החלוקה, ומכאן השם שבכותרת. למשל, כאשר מחלקים 10/4, התוצאה היא 2.5. החלק השלם של התוצאה הוא 2, או במילים אחרות 4 נכנס ב-10 פעמיים שלמות (ונשארת עוד שארית של 2). כאשר מחשבים 4//10 מקבלים רק את המנה, כלומר 2.

האופרטור // אם כן מעגל את תוצאת החלוקה למטה, כלומר מסיר את השארית שאחרי הנקודה. זו גם הסיבה שבאנגלית קוראים לו floor division – חלוקת “רצפה” (כלומר חלוקה שמעוגלת לרצפה, למטה).

להלן מספר דוגמאות שדרכן נבין את ההבדל בין / ל//. הוסיפו פקודות דומות אם אתם מרגישים צורך לראות עוד דוגמאות:

# Division examples
print(10/4, 10//4)
print(10/3, 10//3)
print(3/4, 3//4)
2.5 2
3.3333333333333335 3
0.75 0

חישוב החלק השברי, זה שמיוצג על ידי הספרות שאחרי הנקודה ונקרא שארית או modulo ומחושב באמצעות האופרטור %.

# Modulo examples
print(10%4)
print(10%4)
print(3%4)
2
2
3

פעולה אריתמתית נוספת שנראה כעת היא פעולה החזקה, המיוצגת ע”י 2 כוכביות **

print(4**3)
print(3**0)
64
1

בחנו את עצמכם

עבור כל אחד מהביטויים הבאים, ענו האם הוא מטיפוס int או float:#

סיכום פעולות אריתמתיות#

אופרטור

שימוש

תיאור

+

x + y

סכום של x ו־y

-

x - y

חיסור y מ־x

*

x * y

כפל של x ב־y

**

x ** y

חזקה של x בחזקת y

/

x / y

חילוק של x ב־y

//

x // y

חילוק שלם של x ב־y: מחזיר את החלק השלם (מעוגל למטה) של תוצאת החילוק

%

x % y

מודולו: השארית של החילוק של x ב־y

טיפול בשגיאות (או מה קורה כאשר כתבנו משהו או נכון?)#

בחנו את עצמכם

חלונית הקוד שלפניכם מופיעה תוכנית בה חלק מהשורות גורמות לשגיאה. עליכם לתקן את כל השגיאות כך שהתוכנית תרוץ עד סופה (ובפרט, בסוף תודפס המילה “success”). ניתן לתקן את השגיאות בכל דרך שתרצו, אך אסור למחוק את כל השורה של פקודה שגורמת לשגיאה.

print( 1 + 2 - 3 * 4 / 5 ! 6)
print(12.3 ** 8 + (12 - 4))
print(14 / (7 - (4 + 3)))
print( 2 + 4) * 6)
print ("<h3>success!</h3>")
  Cell In[24], line 4
    print( 2 + 4) * 6)
                     ^
SyntaxError: unmatched ')'

משתנים (variables) והשמות (assignment)#

אחסון נתונים בזיכרון#

  • תוכניות מחשב מעבדות נתונים

  • הנתונים מתקבלים כקלט או מחושבים ע”י התוכנית

  • כדי להשתמש בהם שוב בהמשך – צריך לזכור אותם

  • לכן, תוכניות משתמשות במשתנים (variables) כדי לשמור נתונים בזיכרון

  • לכל משתנה יש:

    • ערך (התוכן, הנתונים עצמם)

    • שם (קיצור דרך לכתובת בזיכרון)

    • טיפוס (type): סוג המשתנה. לדוגמא:

      • טיפסים שכבר הכרנו: מספרים -int וfloat

      • טקסט/מחרוזת (str) וערכים לוגיים (bool), אותם נכיר בהמשך

משתנים בתוכנית#

  • לכל משתנה יש: שם, ערך, סוג (וכתובת בזיכרון)

  • ב-Python יוצרים משתנים ע”י השמת ערך לשם:

s = "bob"
r = True
age = 35

טיפוסי המשתנים נקבעים אוטומטית לפי ערכים שהוכנסו אליהם והפעולות שבוצעו עליהם

סוגי נתונים – דוגמא#

n = 17
pi = 3.14159
message = "what's up Doc?"
b = True

בחנו את עצמכם

  1. עבור קטע הקוד הבא, קבעו מהו ערכם של המשתנים x,y,z בתום ריצת הקוד

x = 12 
y = 7 
z = x - y 
x = z*2 + 3 
y = z - x + 16
  1. הגדירו שני משתנים - x ו-y. ערכו של x יהיה הגיל שלכם (בשנים), וערכו של y יהיה 3 הספרות האחרונות של מספר הטלפון שלכם (אם הספרה הראשונה מבין ה-3 היא 0 - התעלמו ממנה. למשל: אם 3 הספרות הן 012, אז y = 12).

    הדפיסו – באמצעות הפקודה print – את סכום המשתנים (x+y), הפרש המשתנים (x-y), מכפלת המשתנים (x*y) ומנת המשתנים (x/y). בידקו שהתוצאות אכן נכונות על ידי חישוב ידני או שימוש במחשבון.

# Write your solution here

השמה למשתנים#

  • צד שמאל = שם משתנה

  • צד ימין = ביטוי

n = 10
m = (10 + 4) * 5
  • שם של משתנה: מורכב מאותיות וספרות, ומתחיל באות

המפרש (interpreter):

  • מחשב את הביטוי

  • משייך את הערך לשם המשתנה

משתנים והשמות – דוגמה#

  • שינוי ערך של משתנה

n=10
print(n)
10
n=11
print(n)
11
  • שינוי סוג של משתנה

print(type(n))
n = 1.3141
print(type(n)) 
<class 'int'>
<class 'float'>
  • ניתן להשתמש במשתנים בתוך ביטויים

pi = 3.14159
print(pi * 2 + 1)
7.28318
  • שימוש במשתנה שלא הוגדר יגרום לשגיאת ריצה

check_this
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[32], line 1
----> 1 check_this

NameError: name 'check_this' is not defined

דוגמאות נוספות להשמה#

התנסו עצמכם

a=3
print(a)
b=5
print(b)
c = a + b
print(c)
c = c * 2
print(c)
print(b**a)
print(b/a)
print(b//a)
print(b%a)
3
5
8
16
125
1.6666666666666667
1
2

הפקודה type מחזירה את סוג המשתנה או הביטוי#

a=5
print(a)
5
print(type(4))
<class 'int'>
print(type(3.14159))
<class 'float'>

הבנת קוד באמצעות Python tutor#

התנסו בעצמכם

לפניכם מוצגת חלונית של Python Tutor ובה הקוד אותו ראינו בסרטון. הריצו את הקוד בצורה מבוקרת, כפי שראינו בסרטון. שימו לב איך המשתנים נוצרים ומשתנים בצד ימין של החלונית, וכיצד הפלט מופיע בחלונית הפלט. כשאתם מרגישים שהבנתם איך משתמשים ב-Python Tutor, אתם מוזמנים להמשיך ליחידה הבאה.

השוואות בין מספרים#

לנוחיותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם.

#print(3 < 4)
#print(3 > 4)
x = 3
y = 4
# print(x*2 < y  + 1)
# print(x==y)
# print(x+1 == y)
# x = y
# print(x)
# print(y)a
# print(3 != 4)
# print(3 <= 4)
# print(3 <= 3)
# print(3 >= 4)
print(3 >= 3)
True

בחנו את עצמכם#

import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מה מדפיסה הפקודה הבאה: print(3 * 2 != 6)",
        "type": "many_choice",
        "answers": [
            {
                "answer": "מודפסת הודעת שגיאה - התחביר לא תקין בגלל השימוש בסימן !",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "False",
                "correct": true,
                "feedback": "נכון!"
            },
            {
                "answer": "True",
                "correct": false,
                "feedback": "לא נכון"
            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)
import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מה מדפיסה הפקודה הבאה: print(3 <= 3)",
        "type": "many_choice",
        "answers": [
            {
                "answer": "הודעת שגיאה - לא ניתן להפעיל את האופרטור => על שני מספרים שווים.",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "False",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "True",
                "correct": true,
                "feedback": "נכון!"

            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)

לפניכם קטע קוד ובו 3 משתנים - x,y,z. המשתנים מאותחלים ל-0. לאחר אתחול המשתנים, ישנן מספר הדפסות של פעולות השוואה הכוללות את המשתנים הנ”ל. עליכם לשנות את ערכם של x,y,z עד שכל ההדפסות מדפיסות True.

רמז: יש לפחות משתנה אחד שעבורו יש מספר ערכים שיובילו לפתרון נכון, ויש לפחות משתנה אחד שעבורו יש רק ערך אחד אפשרי.

נסו להבין מיהו המשתנה שעבורו רק ערך אחד אפשרי, והמשיכו משם. בנוסף, הפתרון עשוי לכלול ערכים שאינם שלמים.

x = 0
y = 0
z = 0
print(x + y < z)
print(3*x == 2*y)
print(z < 20)
print(x + 1 == 6)
print(y / 3 >= 2)
False
True
True
False
False

סיכום אופרטורי השוואה#

  • משווים בין משתנים ומחזירים ערך בוליאני (True / False)

אופרטור

שם

תיאור

x < y

קטן מ־

אמת אם x קטן מ־y, אחרת שקר.

x > y

גדול מ־

אמת אם x גדול מ־y, אחרת שקר.

x <= y

קטן או שווה ל־

אמת אם x קטן או שווה ל־y, אחרת שקר.

x >= y

גדול או שווה ל־

אמת אם x גדול או שווה ל־y, אחרת שקר.

x == y

שווה

אמת אם x שווה ל־y, אחרת שקר.

x != y

שונה

אמת אם x שונה מ־y, אחרת שקר.

שימו לב

  • הערכים True וFalse פעולות ההשוואה הן מטיפוס בוליאני (bool). נרחיב את טיפוס זה בהמשך

  • כל אופרטורי ההשוואה שראינו כאן רלוונטיים גם לטיפוסים אחרים יכולים להיות מופעלים גם על טיפוסים אחרים כמו bool וstr. גם על כך נרחיב בהמשך

print(5==5.0)
True
print(6!=2*3)
False
print(3<=3)
True
x=3<3
print(x, type(x))
False <class 'bool'>
print('a'!='b')
True
print(-2>=1)
False

מחרוזות#

על מנת לייצג טקסט, נשתמש בערכים מסוג מחרוזת (string). בפייתון, שם הטיפוס הוא str

מחרוזת מיוצגת ע”י רצף סדור של תווים המוקף בגרשיים או בגרש בודד. לדוגמא, “hello world’ או “hello world’

s = "hello world"
print(s)
print(type(s))
hello world
<class 'str'>

לנוחיותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם.

# print(Hello world!)
# print(3)
# print("3")
# print(3 + "3")
s = "This is a string"
# print(s)
print("3+4 =", 3*4)
3+4 = 12

בחנו את בעצמכם

בתרגיל זה תדפיסו מחרוזת מורכבת שתדפיס את שמכם ואת גילכם. תחילה, הגדירו שני משתנים:

המשתנה הראשון ייקרא name וערכו יהיה מחרוזת עם השם שלכם. המשתנה השני ייקרא age וערכו יהיה הגיל שלכם בשנים.

לדוגמה: סטודנטית בת 22 בשם הילה תגדיר את המשתנים הבאים:

name =  "Hila"
age =  22

לאחר מכן, עליכם להדפיס מחרוזת מורכבת (תוך שימוש בפקודה print עם פסיקים, כפי שהודגם בסרטון) שתדפיס את השם ואת הגיל לפי הפורמט הבא:

"My name is <your name> and I am <your age> years old"

כאשר במקום יופיע השם שלכם כפי שהוגדר במשתנה name, ובמקום יופיע הגיל שלכם כפי שהוגדר במשתנה age. למשל, כאשר הסטודנטית הילה, אותה פגשנו זה עתה, תריץ את הקוד שלה, יודפס:

"My name is Hila and I am 22 years old"

רמז: כדי לייצר מחרוזות מורכבות יש להפריד בין חלקי המחרוזת בעזרת פסיקים.

### write your code here

פעולות על מחרוזות#

לנוחיותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם.

# print("Hello " + "World")
# print("Hello" + " " + "World")
# print("Hello" * 3)
s1 = "Hello"
s2 = s1 * 3
# print(s2)
# print(("Hello" + "World") * 2)
# print(len("a b c d e"))
# print(len(""))
# print("H" in "Hello")
# print("ell" in "Hello")
# print("G" in "Hello")
print("bell" in "Hello")
False

בחנו את בעצמכם

מה מודפס בקטע הקוד הבא:

s="ab"
print(s*(len(s)+len("")))
print(s[0])
print(s[-1])
T
g

אינדקסים של מחרוזות#

a = 'Hello'
print(str.find(a, 'H'))
print(a.find('H'))
0
0
print(a[0])
print(a[1])
print(a[-1])
print(a[4])
H
e
o
o
print(a[5])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[61], line 1
----> 1 print(a[5])

IndexError: string index out of range

גישה לתווים בתוך מחרוזת#

a = 'Hello'
print(a[1])
print(a[1:3])
print(a[1:])
e
el
ello
print(a[-4:-2])
print(a[:-3])
print(a[-3:])
el
He
llo

לנוחותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם:

#print("ab" == "ab")
#print("ab" != "ab")
#print("ab" < "cd")
#print("abc" < "!@#")
s = "Python"
# print(s[0])
# print(s[1])
# print(s[2])
# print(s[3])
# print(s[4])
# print(s[5])
#print(s[6])
print(s[len(s) - 1])
n

סיכום: אופרטורים של מחרוזות#

אופרטור

תיאור

דוגמה

+

שרשור - מחבר ערכים משני צידי האופרטור

a + b יתן 'HelloPython'

*

חזרה - יוצר מחרוזות חדשות ע״י שרשור חוזר של אותה מחרוזת

a*2 יתן 'HelloHello'

[]

חיתוך - מחזיר תו לפי מיקום נתון במחרוזת

a[1] יתן 'e'

[:]

חיתוך טווח - מחזיר תווים בטווח נתון

a[1:4] יתן 'ell'

in

בדיקת חברות - מחזיר אמת אם תו קיים במחרוזת

'H' in a יתן True

not in

בדיקת אי-חברות - מחזיר אמת אם תו לא קיים במחרוזת

'M' not in a יתן True

ייצוג מחרוזות במחשב#

  • לכל תו במחרוזת יש מספר לפי טבלת ASCII

  • המחרוזות נשמרות בזיכרון כרצף מספרים בינאריים

  • ב-Python:

    • \n מייצג ירידת שורה ` מייצג ירידת שורה

    • \t מייצג טאב

טבלת ASCII#

מחרוזות הן אובייקטים בלתי ניתנים לשינוי (immutable objects)#

  • לא ניתן לשנות מחרוזת קיימת

a = "abc"
a[0] = "d"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[67], line 2
      1 a = "abc"
----> 2 a[0] = "d"

TypeError: 'str' object does not support item assignment
  • ניתן להצביע עם משתנה קיים על מחרוזת חדשה

a="abc"
print(a)
a="gggg"
print(a)
abc
gggg

אובייקטים בלתי ניתנים לשינוי#

  • אובייקטים אלו לא ניתנים לשינוי לאחר יצירתם

  • כל פעולה מחזירה משתנה חדש במקום לשנות את המקורי

a = "hello"
b = a.title()
print("a value is:", a)
print("b value is:", b)
a value is: hello
b value is: Hello

פונקציות של מחרוזות (שיטות)#

  • טיפוס str ב-Python ישנן שיטות רבות

print(str.upper('Assaf'))
print(str.upper('Assaf'))
print(str.lower('Noga'))
print(str.replace('Python class occurs on Mondays', 'Mondays', 'Tuesdays'))
print('Py' + 'thon')
print(str.title('python course for engineers'))
print(str.title(str.replace('Python class occurs on Mondays', 'Mondays', 'Tuesdays')))
print('repeat' * 4)
ASSAF
ASSAF
noga
Python class occurs on Tuesdays
Python
Python Course For Engineers
Python Class Occurs On Tuesdays
repeatrepeatrepeatrepeat

פונקציות נוספות של מחרוזות#

  • len

  • find, startswith, endswith

  • isalpha, isdigit, islower

  • join, replace

  • strip, rstrip

  • split

השיטות האלו חשובות מאוד! חובה להכיר אותן כדי לפתור בעיות רבות.

למידע נוסף: http://www.tutorialspoint.com/python/python_strings.htm
חפשו בגוגל שיטות נוספות של str

המרות טיפוסים#

  • באופן עקרוני ניתן לבצע המרה מכל טיפוס לכל טיפוס.

  • ההמרה תתבצע בהצלחה רק אם הערך שאותו מנסים למהיר “הגיוני” עבור טיפוס אליו מנסים להמיר

    • לדוגמא את המחרוזת “12” נוכל להמיר לטיפוסים int וfloat, אך “10.5” נוכל להמיר בהצלחה לfloat בלבד, ואת “hello world” לא ניתן להמיר בהצלחה באף אחד מהטיפוסים הללו

    • לעומת זאת, ניתן להמיר כל מספר (int וfloat) לstr

  • המרה שנכשלת תחזיר שגיאה

  • ניתן לבצע המרה גם לטיפוסים שנלמד בהמשך

התנסו בעצמכם

num = 123
print(num, type(num))
num_str = str(num)
print(num, type(num))
num_float = float(num)
print(num_float, type(num_float))
123 <class 'int'>
123 <class 'int'>
123.0 <class 'float'>

טיפוס בוליאני ואופרטורים בוליאניים#

טיפוס בוליאני מייצג אמת ושקר, כלומר קיימים רק 2 ערכים אפשריים בלבד לטיפוס זה: True ו-False.

שימו לב#

  • True ו-False הן מילים שמורות בשפה (בדומה ל+ ‘=’ וכו’), כלומר, לא ניתן להשתמש בהם לצרכים אחרים כמו הגדרת משתנים

  • True ו-False תמיד יופיעו עם אות גדולה בהתחלה ואותיות קטנות בהמשך

טיפוסים בוליאניים שימושיים בבדיקות שנעשה על הנתונים שלנו הם התוצאות של פעולות ההשוואה שכבר פגשנו, וניתן להמשתמש בהם גם לצורך בניית תכניות מורכבות באמצעות תנאים ולולאות כפי שנראה בהמשך

a = True
b = 2>1 
c = False
d = 1>2

אופרטורים בוליאניים פועלים על ערכים בוליאניים ומחזירים ערך בוליאני

קיימים שלושה אופרטורים לוגיים: and or ו-not

האופרטור and#

  • תחביר: a and b

  • מחזיר True אם גם a וגם b הם True. אחרת, מחזיר False

a

b

a and b

True

True

True

True

False

False

False

True

False

False

False

False

דוגמא

נסו בעצמכם

a=True
b=True
print(a and b)

a=2>1
b=2<1
print(a and b)


print(False and False)
True
False
False

האופרטור or#

  • תחביר: a and b

  • מחזיר True אם לפחות אחד מהמשתנים a או b הם True. אחרת, מחזיר False

a

b

a or b

True

True

True

True

False

True

False

True

True

False

False

False

דוגמא

נסו בעצמכם

a=True
b=True
print(a or b)

a=2>1
b=2<1
print(a or b)


print(False or False)
True
True
False

האופרטור not#

  • תחביר: not a

  • מחזיר True אם a הוא False. אחרת, מחזיר True

a

not a

True

False

False

True

דוגמא

נסו בעצמכם

a=True
print(not a)

a=2<1
print(not a)


print(not False)
False
True
True

שירשור אופרטורים לוגיים#

בדומה לפעולות אריתמתיות, ניתן לשרשר מספר אופרטורים לוגיים ברצף סדר פעולות:

  • and קודם לor(כמו שכפל קודם לחיבור)

  • not קודם לכולם

דוגמא

נסו בעצמכם

print (True and True and False)

print ((2>1 or 1<2) and 1==1)
print ((2>1 or 1<2) and 1==1)
print ((2>1 or 1<2) and not 1==1)
print (not 2==2 or 1==1)
False
True
True
False
True

סיכום אופרטורים לוגיים#

אופרטור

תיאור

x and y

שניהם נכונים: True, אחרת: False

x or y

לפחות אחד מהם נכון: True, אחרת: False

not x

אם x הוא False –> התוצאה היא True, אם x הוא True –> התוצאה היא False

פונקציות (חלק 1)#

איך נחשב את ההיקף של שלושה מלבנים?#

c1=3*2+3*2
print(c1)
c2=1*2+3*2
print(c2)
c3=3*2+5*2
print(c3)
12
8
16

כפילות בקוד#

כפילות בקוד היא בעיה#

  • באגים משוכפלים – קשה לתקן

  • קוד ארוך יותר

  • שגיאות Copy & Paste

פתרון: מימוש כפונקציה כותבים פעם אחת – משתמשים שוב ושוב

הגדרת פונקציה#

  • רצף פקודות עם שם, שמבצע משימה מסוימת – באופן עצמאי משאר הקוד

למה פונקציות?#

  • מודולריות – חלוקה למשימות קטנות, קוד לשימוש חוזר

  • הפשטה – פותרים פעם אחת, עוטפים בפונקציה

  • תחזוקה – תיקון באגים במקום אחד

  • קריאות – הקוד הראשי קצר יותר

  • טווח משתנים מוגבל – משתנים זמניים רק בתוך הפונקציה

פונקציות מובנות#

  • השתמשנו כבר בכמה פונקציות מובנות כמו n()וtype()`` le

type(5)
int
len("abcde")
5

בפייתון יש כמה וכמה פונקציות מובנות. אלו פונקציות שלדעת מפתחי השפה שימושיות ביותר, ותוכניות רבות עושות בהן שימוש, ולכן הוחלט לממש אותן כחלק מובנה בשפת פייתון.

ראינו למשל את הפונקציה המובנית len. פונקציה זו כאמור מקבלת מחרוזת או רשימה, ומחזירה לנו את האורך שלהן – כלומר מספר התווים במחרוזת או מספר האיברים ברשימה. למעשה, הפונקציה הזו יכולה לקבל עוד כמה טיפוסי נתונים בפייתון שלא פגשנו, כמו קבוצה (set), מילון (dict) ועוד, אך לא נעסוק בזה כאן.

השימוש בפונקציה len כבר הודגם. למשל אם נכתוב את הפקודות:

n = len("This is a string")
print(n)

יודפס לנו 16.

שימו לב מה בדיוק קרה כאן: בפקודה הראשונה קראנו לפונקציה len ע”י כתיבת שמה ואז סוגריים עגולים. בתוך הסוגריים, רשמנו את המחרוזת שאת אורכה רצינו להדפיס. זהו הקלט של הפונקציה, שנקרא גם הפרמטר (parameter) שלה, מושג שעוד נתעמק בו בהמשך בשיעור. הפונקציה פעלה כפי שפעלה, בהתאם להגדרתה על ידי מפתחי שפת פייתון. מבחינתנו כאמור זוהי מעין “קופסה שחורה” – אנחנו לא צריכים לדעת איך בדיוק הפונקציה עובדת, אלא רק מהו אופן השימוש בה. ואכן, הפונקציה החזירה לנו כפלט את אורך המחרוזת, 16, אותו שמרנו במשתנה בשם n (זהו שם מאוד מקובל לשמירת מספרים שלמים, ובפרט אורכי מחרוזות או רשימות. אבל כמובן יכולנו להשתמש בשם אחר).

בפקודה השניה קראנו לפונקציה מובנית נוספת בפייתון – הפונקציה print. זוהי פונקציה שמקבלת ערך כלשהו כקלט. פעולתה של הפונקציה print היא הדפסת הערך שקיבלה (למסך, אם לא הגדרנו משהו אחר). ומה הפלט של הפונקציה print? כאן קורה משהו מעט מבלבל, אז בואו נחכה עם זה כמה רגעים, ומייד נחזור לנקודה הזו.

אם כן, יש לנו בפקודה התמימה הזו קריאה לשתי פונקציות, קודם len, שקיבלה את הקלט “This is a string” והחזירה כפלט את המספר 16, ואז התבצעה קריאה לפונקציה print שקיבלה כקלט את המספר 16, ופשוט הדפיסה אותו.

יכולנו גם לוותר על המשתנה n ולכתוב את שתי הפקודות כך:

print(len("This is a string"))

התוצאה היא בדיוק אותה תוצאה. פשוט במקום לשמור את תוצאת הקריאה ל- len במשתנה ואז להעביר אותו לפונקציה print, עשינו זאת בבת אחת. את הפקודה הזו צריך לקרוא “מבפנים החוצה” – קודם קוראים ל- len, ואת מה שהיא מחזירה (16 בדוגמה הזו) מעבירים מייד ל- print לצורך הדפסה.

אם כן, זיכרו את הנקודה החשובה הבאה: ערך שמוחזר מפונקציה יכול להישמר במשתנה, ואז ניתן לעשות שימוש במשתנה הזה ככל שדרוש, או לחילופין אפשר להשתמש בערך המוחזר מייד בלי משתנה עזר, ולמשל להעביר אותו ישירות כקלט לפונקציה אחרת. הדרך הראשונה (שימוש במשתנה) מתאימה כאשר אנחנו רוצים להשתמש בערך שאותו החזירה הפונקציה יותר מפעם אחת. למשל:

n = len("This is a string")
print(n)
if n > 10:
    print("this is a long string")
elif n < 5:
    print("This is a short string")
בדוגמה הזו, אילו לא שמרנו את אורך המחרוזת במשתנה, היה עלינו לקרוא לפונקציה len שוב ושוב:

print(len("This is a string"))
if len("This is a string") > 10:
    print("this is a long string")
elif len("This is a string") < 5:
    print("This is a short string")

זה כמובן מסורבל יותר. בנוסף, אם פתאום נחליט לשנות את המחרוזת מ- This is a string למשהו אחר, למשל This is my string, ניאלץ לשנות זאת בשלושה מקומות! מעבר לכך, קריאה חוזרת לפונקציה עלולה להשפיע לרעה על זמן הריצה של התוכנית (אם כי לא במקרה זה, בו זמן הריצה הוא ממש זניח, כמה מילי שניות וזהו).

נחזור עכשיו לשאלת הפלט של הפונקציה print().

שימו לב לפקודות הבאות:

result = print(1+2)
print(result)
3
None

כפי שאתם רואים, ההדפסה הראשונה היא כמובן של הערך 3. ההדפסה השניה, של המשתנה result נתנה לנו את הערך None. זו הדרך של פייתון לומר “כלום”. זהו ערך מיוחד בפייתון שמשמש בדיוק למקרים כאלו, בהם פונקציה מסויימת לא מחזירה שום ערך. וזה מה שקורה בפונקציה print, היא למעשה לא מחזירה שום פלט. שימו לב – ההדפסה עצמה היא הפעולה של הפונקציה print, בדומה לכך שפעולתה של הפונקציה len היא חישוב האורך. אבל מעבר לפעולת ההדפסה אין ל- print שום פלט (או ליתר דיוק יש לה פלט ריק). זה יכול מעט לבלבל. אבל פשוט זיכרו – אל תשמרו או תנסו לבצע פעולות על הערך שמחזירה print אף פעם. הנה דוגמה:

print(3)+print(4)
3
4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[82], line 1
----> 1 print(3)+print(4)

TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'

אם תריצו את הפקודה, תגלו שלאחר הדפסת הערך 3 ואז הערך 4, נעשה נסיון לחבר את הערכים שהקריאות ל-print החזירו. למעשה ביקשנו מפייתון לחבר “כלום” עם “כלום” (שימו לב – לא 0 עם 0!), ולכן נקבל הודעת שגיאה:

unsupported operand type(s) for +: 'NoneType' and 'NoneType'

הפעולה + לא מוגדרת על ערכים מטיפוס None.

לסיום, חשוב להזכיר שתי טעויות נפוצות מאוד בשימוש בפונקציות. האחת קשורה לקלט, והשניה לפלט.

1. העברת קלט לא חוקי לפונקציה.

מה קורה אם נתתם לפונקציה קלט שאינו מתאים עבורה? אם הקלט ממש לא חוקי, נקבל הודעה שגיאה. למשל, אם ננסה לקרוא לפונקציה sorted על רשימה שמכילה גם מחרוזות וגם מספרים. פייתון כזכור יודע להשוות מספרים למספרים, וגם מחרוזות למחרוזות. אבל לא מספרים למחרוזות. לכן פקודה כמו:

print(sorted([1,2,3,"computer"]))

תגרור הודעת שגיאה.

פונקציות מובנות נוספות ניתן למצוא כאן

הגדרת פונקציה חדשה ב-Python#

כתיבת פונקציה:#

def function_name(parameter1, parameter2,...):
    statement1
    statement2
    statement3
    ...
    return result1, result2, ...
  • שימו לב לכניסות (indentation)!

  • return היא פקודה אופציונלית

    • אם לא נכתבת – מוחזר None

קריאה לפונקציה:#

var1, var2, = function_name(val1, val2,...)

נחזור לדוגמה שלנו: חישוב היקף מלבנים#

הגדרת הפונקציה#

def circumference(x,y):
    return 2*x +2*y

שימוש בפונקציה (קריאה לה)#

a = circumference(4,6)
print(a)
print(circumference(2,3))

קלט ופלט של פונקציות#

  • קלט: פרמטרים (arguments) – יכולים להיות מכל סוג

  • פלט: פקודת return

    • מחזירה ערך/ים (כל סוג), או None

שימו לב

  • return מפסיק מיידית את ריצת הפונקציה ומחזיר ערך

  • פקודות return וprint מבצעות דברים שונים

    • print פיסה למסך ואינה מחזירה דבר (מחזירה None)

    • return מחזירה ערך אבל לא מדפיסה למסך

def foo1(x):
    return x

def foo2(x):
    print("x value:", x)

res1=foo1(x)
print('res1 value:', res1)
res2=foo2(x)
print('res2 value:', res2)
res1 value: 20
x value: 20
res2 value: None
def print_lyrics():
    print("The wheels on the bus go round and round")
    print("Round and round, round and round")
def repeat_lyrics(): 
    print_lyrics() 
    print_lyrics()
    
repeat_lyrics()

אפשר לבדוק את זה פה:
Python Tutor

העמקה#

עד כה למדנו מהן פונקציות, והדגמנו שימוש בפונקציות מובנות של פייתון. הפונקציות המובנות של פייתון עונות על כמה צרכים בסיסיים ונפוצים, אבל בהרבה מקרים אין פונקציה מובנית שמתאימה לצרכינו.

בכעת אנו לומדים לכתוב פונקציות משל עצמנו. פונקציות כאלו ישמשו אותנו (או מתכנתים אחרים) בדיוק באותו אופן שהפונקציות המובנות של פייתון שימשו אותנו. כלומר לאחר שבנינו פונקציה חדשה, נוכל לקרוא לה עם הפרמטרים המתאימים, והיא תחזיר לנו את הפלט המצופה. כזכור, פונקציות כאלו נקראות לעיתים “קופסאות שקופות”. בשונה מקופסאות שחורות, פרטי הפונקציות שאנחנו כתבנו גלויים לנו כמובן.

בעת בניית פונקציה חדשה עלינו לחשוב תחילה על הנקודות הבאות:

1. איזה שם נרצה לתת לפונקציה?

נרצה לתת לפונקציה החדשה שלנו שם משמעותי, שמעיד על פעולתה. למשל, אם הפונקציה מחשבת ממוצע של רשימת מספרים, כדאי לקרוא לה average או avg. פונקציה שמקבלת מחרוזת והופכת אותה משמאל לימין תיקרא למשל reverse ולפונקציה שבודקת אם מספר נתון הוא ראשוני כדאי לקרוא לדוגמה is_prime.

2. מהם הקלטים (שם אחר: פרמטרים) שהפונקציה צריכה לקבל? כמה כאלו יש ואילו שמות כדאי לתת להם?

גם כאן מומלץ לתת לפרמטרים שמות משמעותיים.

פונקציה לחישוב ממומצע של רשימת מספרים צריכה לקבל פרמטר אחד - רשימת מספרים. רשימות ייקראו לרוב lst, my_list וכד’. כדי להדגיש שמדובר ברשימת מספרים ולא “סתם” רשימה, אפשר לקרוא לה למשל num_lst. אם מדובר ברשימה בעלת משמעות ספציפית יותר, לדוגמה רשימת ציונים, אפשר לקרוא לה grade_lst.

פונקציה להיפוך מחרוזת צריכה לקבל את המחרוזת שאותה רוצים להפוך. אם מדובר במחרוזת ללא הקשר ספציפי, נקרא לה פשוט s או st או string או text וכו’. אם מדובר למשל בשם של אדם אפשר לקרוא לה name, וכו’.

כדי לבדוק אם מספר הוא ראשוני הפונקציה צריכה לקבל מספר שלם. שמות מקובלים למספרים שלמים הם אותיות בודדות קטנות באנגלית, למשל a, b, c ולפעמים n, m. אם יש לנו יותר משלושה או ארבעה מספרים בקלט, נוח לקרוא להם למשל n1, n2, n3, …. גם כאן, אם המספר הוא בעל משמעות ספציפית יותר, כדאי שהשם יישקף זאת. למשל אם המספר הוא קוד סודי כלשהו או סיסמה, נקרא לו code או pass_num וכו’.

3. מה הפלט שהפונקציה אמורה להחזיר ומה הטיפוס שלו?

אם חישבנו ממוצע של רשימת מספרים, הפלט הוא מספר, לא בהכרח שלם. כלומר ערך מטיפוס float. פונקציה להיפוך מחרוזת תחזיר את תמונת המראה של המחרוזת, כלומר ערך מטיפוס str. ואילו פונקציה לבדיקה האם מספר הוא ראשוני תחזיר True (אם הוא ראשוני) או False (אם הוא לא ראשוני), ובכל מקרה ערך מטיפוס בוליאני (bool).

כדי להדגים כתיבת פונקציה חדשה בפייתון, נראה פונקציה לחישוב מקסימום בין שני מספרים. אגב, כזכור ישנה הפונקציה max בפייתון. היא מתוחכמת יותר מהבחינה שהיא יכולה לקבל כקלט שניים, שלושה, או מספר כלשהו של ערכים. הדוגמה שנראה מייד תאפשר לנו להציץ אל מתחת ל”מכסה המנוע” של max. אבל רק בשיעור 3 נבין באמת איך אפשר לחשב מקסימום בין מספר לא ידוע מראש של ערכים.

חישוב מקסימום בין שני ערכים – הפונקציה max2#

נבחן תחילה את 3 הנקודות שהזכרנו קודם.

  1. מכיוון שהפונקציה שאנחנו רוצים לכתוב אמורה לחשב מקסימום בין שני ערכים, סביר מאוד לקרוא לה max2 (גם כדי להבחין אותה מ- max של פייתון, וגם כי יהיו לנו max3, max4 ועוד בהמשך…).

  2. הפונקציה max2 תקבל כקלט שני ערכים – שני מספרים. נקרא להם a ו- b.

  3. הפונקציה אמורה להחזיר ערך ששוה לאחד משני המספרים – הגדול מביניהם (אם הם שווים אז לא משנה איזה מהם נבחר).

כך תיראה הפונקציה בפייתון:

def max2(a,b):
    if a > b:
	    return a
    else:
	    return b

בואו נעבור על המרכיבים השונים. התחלנו עם המילה def שאומרת שאנחנו הולכים להגדיר כעת פונקציה חדשה. לאחר מכן רשמנו את השם שבחרנו לפונקציה, ואז, בתוך סוגריים עגולים, את השמות שבחרנו לפרמטרים, מופרדים בפסיקים. לאחר מכן נקודתיים. עד כאן רשמנו את ה”כותרת” של הפונקציה.

כעת נותר לרשום מה הפונקציה עושה. כדי לחשב מיהו הערך הגדול יותר, נשתמש במשפט תנאי. נשאל האם a>b, ואם כן, הפונקציה תסיים את פעולתה עם a כפלט. ב”תסיים את פעולתה” הכוונה שמי שקרא לפונקציה יקבל בחזרה את הערך של a. זה קורה באמצעות הפקודה return a. כלומר ברגע שמגיעים לפקודת return בעת ביצוע של פונקציה, הפונקציה מסיימת ומחזירה את הערך שכתוב אחרי המילה return למי שקרא לפונקציה. באופן דומה, אם התנאי לא מתקיים (כי a לא גדול מ- b, כלומר b גדול או שווה ל- a), הפונקציה תסיים את עבודתה אבל תחזיר את b.

ברגע שסיימנו להגדיר פונקציה, היא מוכנה לפעולה. אפשר לקרוא לה ממש כמו שקראנו לפונקציות המובנות של פייתון. למשל, הריצו את הקוד הבא:

res = max2(5,7)
print(res)
7

בחנו את עצמכם

לפניכם פונקציה קצרה בפייתון המקבלת מחרוזת לא ריקה המכילה ספרות בלבד.

def avg(s):
    return int(s[0])/len(lst)

תנאים (if)#

בחנו את עצמכם

לפניכם תרשים זרימה:

משפטי התנאי if וif-else בפייתון#

לנוחותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם:

temp = 18

if temp < 20:
    print("Eat soup!")
    print("Enjoy!")
else:
    print("Eat a salad!")
print("Bon appetit!")
Eat soup!
Enjoy!
Bon appetit!

סיכום: תחביר תנאי פשוט (if)#

משפטי תנאי (או פקודות תנאי) הם סוג פקודות בסיסי בתכנות המאפשר לנו לשלוט בסדר הפעולות של התוכנית אותה אנחנו כותבים. משפטי תנאי מאפשרים להתנות ריצה של חלק מסוים בקוד בקיומו (או אי-קיומו של תנאי מסוים). ראינו כמה דוגמאות לכך: הערה: יופיעו כעת מספר קטעי בהם יופיע תנאי כללי בשם condition. תנאי זה הוא בעל ערך בוליאני בפייתון, כלומר ערכו הוא True או False. כאשר אנחנו כותבים תוכנית בפייתון, תנאי זה יכול ללבוש צורה של כל ביטוי בעל ערך בוליאני, כמו למשל 3>5 (False), 3==3 (True) וכו. הצורה הבסיסית ביותר היא ביצוע פקודות מסוימות אם תנאי מסוים מתקיים. במקרה זה הקוד בנוי כך:

if condition:
    statement1
    statement2
statement3

שימו לב – לאחר משפט התנאי (שמתחיל ב-if) יש צורך לשים נקודותיים

אם ערכו של condition הוא True, אז יורצו השורות statement1 ו-statement2 (המוזחות ארבעה רווחים או טאב ימינה), ולאחר מכן ירוץ statement3. הקוד שנמצא מתחת לשורה שמתחילה ב-if אם ערכו של condition הוא False, נדלג על המוזח ימינה (statement1 ו-statement2) ונמשיך לקוד הבא בתכנית (statement3)

תרשים סיכום לתנאי פשוט (if):#

דוגמא נוספת ל־if#

הקוד הבא בודק אם מספר הקלט מתחלק ב18

נסו בעצמכם

def divisible(num):
    if num % 18 == 0:
        print(num, "is divisible by 18")
    print("Goodbye")
divisible(53) 

סיכום: תחביר if-else#

צורת תנאי נוספת היא ביצוע פקודות מסוימות כאשר תנאי מסוים מתקיים, ופקודות אחרות כאשר התנאי אינו מתקיים. במקרה זה הקוד בנוי כך:

if condition1:
    statement1
else:
    statement2

statement3

גם כאן אם condition הוא True ירוץ הקוד שמתחת ל-if, אך אם condition הוא False, ירוץ דווקא הקוד שנמצא מתחת ל-else. שימו לב שגם לאחר ה-else מופיעות נקודותיים. נדגיש כי במבנה כזה של משפט תנאי בכל מקרה אחד מקטעי הקוד הנ”ל ירוצו, בהתאם לערכו של condition. לאחר ריצת אחד מקטעי הקוד התוכנית ממשיכה לרוץ לפי הקוד שאחרי משפטי התנאי האלו.

הזחה:#

  • else משויך ל־if, אם הוא ברמה מקבילה אם הוא בא מיד לאחר השורות שבתוך הif (או הelif כפי שנלמד בהמשך), וכן, נמצא באותה רמת הזחה כמו הif

  • הפקודות שבתוך else מוזחות גם הן פנימה

תרשים סיכום ל-if-else:#

דוגמא נוספת ל־if-else#

הקוד הבא מקבל 2 צלעות סמוכות של מלבן ומחזירה אם המלבן הוא גם ריבוע

נסו בעצמכם

def is_square(width, height):
    if width == height:
        print("found a square")
    else:
        print("found a rectangle")
    print("done")
is_square(4,4)

בחנו את עצמכם

בתרגיל זה אתם תכתבו קוד פייתון שיעזור למשתמש להחליט (לפני שהוא יוצא מהבית) האם עליו לקחת כובע, מעיל, או מטריה.

ההחלטה נעשית לפי תרשים הזרימה הבא:

הקלט לבעיה הוא שני משתנים - מספר בשם temp שערכו הוא הטמפרטורה בחוץ, ומשתנה בוליאני (משתנה שערכו אמת או שקר) בשם is_raining - כאשר is_raining הוא True אז יורד גשם בחוץ.

עליכם “לתרגם” את תרשים הזרימה לקוד הכולל תנאי if ו-else, בדומה למה שראינו בסרטון. כדי להחליט אם ניקח כובע, מעיל, או מטריה, אתחלנו עבורכם 3 משתנים בוליאניים ששמותיהם hat (כובע), coat (מעיל), ו-umbrella (מטריה). אם לפי תרשים הזרימה צריך לקחת את אחד מהפריטים האלו - שנו את ערכו במקום המתאים בקוד ל-True, ואם לא צריך - שנו אותו ל-False. למשל - אם הטמפרטורה בחוץ היא 20 מעלות ולא יורד גשם - אז צריך להתקיים hat = True, coat = False, umbrella = False. הקפידו לכתוב True ו- False עם אות ראשונה גדולה.

בדקו את הקוד שלכם - שנו את ערכי משתני הקלט של הבעיה (temp ו-is_raining) והריצו את הקוד. הפתרונות שלכם ייבדקו מול הפתרון הנכון, ותוכלו לקבל על כך משוב בחלונית הפלט.

# input variables
temp = 20
is_raining = False

# output variables
hat = False
umbrella = False
coat = False

# Write you solution here:

פתרון#

# input variables
temp = 20
is_raining = False

# output variables
hat = False
umbrella = False
coat = False

# Check temperature
if temp > 15:
    # In case it is hot
    hat = True
    coat = False
else:
    # In case it is not hot
    hat = False
    coat = True

# Check if raining    
if is_raining:
    # If it's raining
    umbrella = True
else:
    # If it's not raining
    umbrella = False
    
# Print results    
if hat:
    print("You should take a hat")
else:
    print("You shouldnt take a hat")
    
if coat:
    print("You should take a coat")
else:
    print("You shouldnt take a coat")
    
if umbrella:
    print("You should take an umbrella")
else:
    print("You shouldnt take an umbrella")
You should take a hat
You shouldnt take a coat
You shouldnt take an umbrella

תנאים מקוננים (nested ifs) או, תנאי בתוך תנאי#

לנוחותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם:

temp = 25
wait = 60

if temp < 20:
    print("Eat soup!")
    print("Enjoy!")
    if wait >= 40:
        print("Order a delivery")
    else:
        print("Prepare dinner yourself")
else:
    print("Eat a salad!")
print("Bon appetit!")
Eat a salad!
Bon appetit!

דוגמא נוספת לתנאים מקוננים#

הקוד הבא בודק אם מספר הקלט מתחלק ב2, 3 ו6 ומדפיס את הטקסט המתאים

נסו בעצמכם

def is_divisible(n):
    if n % 3 == 0: 
        if n % 2 == 0: # NESTED if
            print('divisible by 2,3,6')
        else: # NESTED else, pertains to INNER if.
            print('divisible by 3')
    else: # Not nested, thus pertains to OUTER if.
        if n % 2 == 0: # NESTED if
            print('divisible by 2')
        else:
            print(n + ' is not divisible by 3.')

משפט תנאי if-elif-else#

כאשר יש לנו הרבה תנאים מקוננים במבנה של if…else, התוכנית שלנו עלולה “להימתח” ימינה בצורה מוגזמת:

if תנאי 1:
	
else:
	if תנאי 2:
		
	else:
		if תנאי 3:
			
		else:
			if תנאי 4:
				
			else:

כדי להימנע מזה, בפייתון ניתן לקצר את:

else:
    if תנאי: 

באופן הבא:

elif תנאי: 

כלומר elif הוא קיצור של else ומייד אחריו if.

התוכנית שלעיל תיראה כך:

if תנאי 1:
elif תנאי 2:
elif תנאי 3:
elif תנאי 4:

בחנו את עצמכם

  1. לפניכם פונקציות foo1 ו-foo2

def foo1(x):
    if x < 10:
        x=x+8
    else:
        x=x+1

def foo2(x):
    if x<10:
        x=x+8
    elif x>20:
        x=x+1
  1. לפניכם תוכנית קצרה:

def foo3(x):
    if x > 10: 
    	x = x + 2
    if x > 6:
    	x = x * 2
    if x <  10:
    	if x == 5:
    		x = x * 3
    	else:
    		x = x * 10
    elif x <  20: 
    	x = x * 4
    if x > 7: 
    	x = x * 2
    if x > 2: 
    	x = x - 10

    return(x)
import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מלאו בתיבה את הערך אותו תחזיר הקריאה foo3(5)",
        "type": "numeric",
        "answers": [
            {
                "type": "value",
                "value": 20,
                "correct": true,
                "feedback": "נכון!"
            },
            {
                "type": "default",
                "feedback": "לא נכון"
            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)

if-elif-else#

elif = else if#

if condition1:
    statement1
elif condition2:
    statement2
else:
    statement3

rest of code
  • אם condition1 נכון → statement1

  • אם condition1 שגוי ו־condition2 נכון → statement2

  • אחרת → statement3

  • לבסוף: המשך הקוד

def which_triangle(a,b,c):
    if a == b and b == c:
        x="Equilateral triangle"
    elif a==b or a==c or b==c:
        x="Isosceles triangle"
    else:
        x="another kind of triangle"
    return x
result=which_triangle(4,4,4)
print(result)

שימוש באופרטורים לוגיים בתנאים#

נניח שאנחנו מעוניינים לבדוק האם משתנים להלן שווים כולם זה לזה.

a = 111111111111 * 111111111111
b = 12345679012308641986431 + 12345667890
c = 12345679110300785634118 - 979797979797979

אפשר כמובן להדפיס את המספרים ולבדוק זאת בעין, אבל המספרים האלו גדולים וזה לא יהיה כיף גדול (וגם אנחנו עלולים לטעות בקלות).

לעומת זאת, בעזרת שימוש בתנאים, ישנה דרך פשוטה לבדוק אם כל המספרים שווים זה לזה מבלי להדפיס אותם. הנה תוכנית בפייתון שעושה זאת:

if a == b:
    if b == c:
        print("All numbers are equal")
    else:
        print("Not all numbers are equal")
else:
    print("Not all numbers are equal")

שימו לב שאין צורך לבדוק האם a == c כי ברגע שגילינו שגם a == b וגם b == c מתחייב ש-a == c הוא אמת.

את התוכנית הזאת היה אפשר לכתוב באופן מעט יותר נעים לעין, וגם לחסוך פקודת הדפסה אחת, ע”י שימוש באופרטור הלוגי and (וגם):

if a == b and b == c:
    print("All numbers are equal")
else:
    print("Not all numbers are equal")
Not all numbers are equal

המילה and משמשת כ”דבק” שמחבר שני תנאים בסיסיים לתנאי אחד מורכב.

כפי שלמדנו, לחבר באמצעות and יותר מספר ערכים בוליאניים. למשל:

a = 111111111111 * 111111111111
b = 12345679012308641986431 + 12345667890
c = 12345679110300785634118  979797979797979
d = 12345679110300785634118  97979797979797

if a == b and b == c and c == d:
    print("All numbers are equal")
else:
    print("Not all numbers are equal")

באופן דומה, ניתן להשתמש באופרטור הלוגי or (או) כדי לבדוק אם לפחות אחד התנאים מתקיים. במקרה שלנו, היינו משתמשים בor אילו רצינו לבדוק אם מבין המספרים a, b ו-c יש שניים ששווים זה לזה:

if a == b or b == c or a == c:
    print("Some of the numbers are equal")
else:
    print("All numbers are different")
Some of the numbers are equal

שימו לב שכדי לבדוק אם יש שני ערכים שווים מבין a, b, c היינו צריכים לבדוק את כל שלוש האפשרויות, כפי שרואים בקוד.

הנה עוד דוגמה:

a = 12
if a == 10 or a == 11 or a == 12 or a == 13:
    print("a is between 10-13")
a is between 10-13

כאן אנחנו בודקים האם הערך של המשתנה a הוא 10 או 11 או 12 או 13. שימו לב שיש לחזור על התנאי במלואו בכל פעם. טעות נפוצה היא לנסות לקצר ולכתוב a == 10 or 11 or 12 or 13. זה לא עובד בפייתון, כי כל אחד מהתנאים הבסיסיים צריך לבדוק “האם a שווה ל…”.

בחנו את עצמכם

  1. נתונה הפונקציה foo1 להלן:

def foo1(st):
    if "A" in st:
        return st
    elif len(st) > 3 or st[0] == "A" or st + "f" == "abcdef":
        return st*2
    else:
        return "what a nice day!"
import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מה תחזיר הקריאה foo1('abcde')?",
        "type": "many_choice",
        "answers": [
            {
                "answer": "לא יוחזר כלום (None)",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "abcdeabcde",
                "correct": true,
                "feedback": "נכון!"
            },
            { 
                "answer": "!what a nice day",
                "correct": true,
                "feedback": "נכון!"

            },
            { 
                "answer": "abcde",
                "correct": true,
                "feedback": "נכון!"

            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)
  1. נתונה הפונקציה foo2 להלן:

def foo2(x,y,z):
    if z == y and (x != 6 or y > 1):
        print("hey!!!")
    else:
        print("Hi…")
import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מה תחזיר הקריאה foo2(6,4,'y')?",
        "type": "many_choice",
        "answers": [
            {
                "answer": "לא יוחזר כלום (None)",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "תתקבל שגיאה",
                "correct": false,
                "feedback": "לא נכון"
            },
            { 
                "answer": " …Hi",
                "correct": true,
                "feedback": "נכון!"

            },
            { 
                "answer": "!!!hey",
                "correct": false,
                "feedback": "לא נכון"

            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)

דוגמא מסכמת: פונקציות ותנאים#

לנוחותכם חלונית עם הקוד שראינו בסרטון. מוזמנים להריץ בעצמכם:

def max2(a,b):
    if a > b:
        return a
    else:
        return b

# result = max2(3,5)
# print(result)
# result2 = max2(4,-5)
# print(result2)
x = 4
y = -5
#result3 = max2(x,y)
#print(result3)
result4 = max2(x + y + 3, x*y)
#print(result4)

def max3_v1(a,b,c):
    if a > b:
        if a > c:
            return a
        else:
            return c
    else:
        if b > c:
            return b
        else:
            return c

result5 = max3_v1(1,2,3)
#print(result5)

def max3_v2(a,b,c):
    if a > b and a > c:
        return a
    elif b >= a and b > c:
        return b
    else:
        return c

result6 = max3_v2(1,2,3)
print(result6)
3

בחנו את עצמכם

הפונקציה הבאה מצפה לקבל כקלט שני משתנים, מחרוזת st ותו בודד c. מה תחזיר הפונקציה עבור קלט שכזה

def what(st, c):
    if c in st:
        return True
    else:
        return False
import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מה תחזיר הפונקציה?",
        "type": "many_choice",
        "answers": [
            {
                "answer": "האם מחרוזת נתונה st מכילה את תו נתון כלשהו c",
                "correct": true,
                "feedback": "נכון!"
            },
            {
                "answer": "כמה פעמים תו נתון כלשהו c מופיע במחרוזת נתונה st",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "האם מחרוזת st מכילה את האות השלישית באלפבית האנגלי c",
                "correct": false,
                "feedback": "לא נכון"

            },
            { 
                "answer": "כמה פעמים האות c (האות השלישית באלפבית האנגלי) מופיעה במחרוזת נתונה st",
                "correct": false,
                "feedback": "לא נכון"

            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)

נתונה הפונקציה להלן

 def what(st, c):
    return c in st
import json
from jupyterquiz import display_quiz
example = \
'''
   [{
    
        "question": "מה תחזיר הפונקציה?",
        "type": "many_choice",
        "answers": [
            {
                "answer": "האם מחרוזת נתונה st מכילה את תו נתון כלשהו c",
                "correct": true,
                "feedback": "נכון! הביטוי c in st ערכו True או False, והפונקציה פשוט מחזירה ערך זה. זהו קיצור מקובל לפונקציה מהתרגיל הקודם."
            },
            {
                "answer": "האם תו כלשהו c נמצא בתחילתה של המחרוזת st",
                "correct": false,
                "feedback": "לא נכון"
            },
            {
                "answer": "האם תו כלשהו c לא נמצא במחרוזת st",
                "correct": false,
                "feedback": "לא נכון"

            },
            { 
                "answer": "כמה פעמים תו נתון כלשהו c מופיע במחרוזת נתונה st",
                "correct": false,
                "feedback": "לא נכון"

            }
        ]
    }]
'''
myquiz = json.loads(example)
display_quiz(myquiz)